# wc.S
#
# - Argumentos:
#	* fd: int
#
# - Stack Frame:
#	* Los 24 superiores se usan para el SRA.	
#	* Los 16 inferiores son espacio reservado para 	
#	  el ABA.

#define 	SSIZE		40
#define		O_FD		36
#define		O_LAST_CHAR	32
#define		O_C		28
#define		O_RA		24
#define		O_FP		20
#define		O_GP		16
#define		O_ARG0		(SSIZE)

#include <mips/regdef.h>
#include <sys/syscall.h>

#void wc(int fd)
#{
#	char c;
#	int last_char = 1;
#	while (read(fd, &c, 1) > 0) {
#		last_char = count(c, last_char);
#	}
#}

.text
.align 2
.globl 	wc
.ent 	wc

wc:
		.frame $fp, SSIZE, ra
		.set noreorder
		.cpload t9
		.set reorder

		subu	sp, sp, SSIZE			#creo el stack
		sw	$fp, O_FP(sp)
		.cprestore O_GP
		sw	ra, O_RA(sp)		
		sw	zero, O_C(sp)
	
		move 	$fp, sp
		sw 	a0, O_ARG0($fp)
		sw	a0, O_FD($fp)
		li	t0, 1
		sw	t0, O_LAST_CHAR($fp)
loop:		li	v0, SYS_read
		lw	a0, O_FD($fp)
		la	a1, O_C($fp)
		li	a2, 1
		syscall
		beqz	v0, unwind
		move	a0, zero
		lb	a0, O_C($fp)
		lw	a1, O_LAST_CHAR($fp)
		la	t9, count
		jal	ra, t9
		sw	v0, O_LAST_CHAR($fp)
		b	loop

unwind:	move 	sp, $fp				#destruyo el stack
		lw	gp, O_GP($fp)
		lw 	ra, O_RA($fp)
		lw	$fp, O_FP($fp)
		addiu 	sp, sp, SSIZE
		jr 	ra	

.end 	wc
